/*
 * Copyright (C) 2009 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <jni.h>
#include <linux/input.h>  
#include <sys/types.h>  
#include <sys/stat.h>
#include "UsbReader.h"

#define DEV_PATH "/dev/input/event2"   //difference is possible
#define dbg_printf(format, arg...)  printf(format,##arg)

/* This is a trivial JNI example where we use a native method
 * to return a new VM String. See the corresponding Java_com_ys_usbreader source
 * fileUtil located at:
 *
 *   apps/samples/hello-jni/project/src/com/example/hellojni/HelloJni.Java_com_ys_usbreader
 */
JNIEXPORT jstring
JNICALL Java_com_ys_usbreader_usbreader_stringFromJNI( JNIEnv* env,
                                                  jclass cls)
{
    return (*env)->NewStringUTF(env, "Hello from JNI !  Compiled with ABI");
}

#define   DEV_PATH_DIR  "/sys/class/input/event%d/device/name"

static int m_fd  = -1 ;
static char dev_path[64] = "/dev/input/event2";
#define  MAX_DIR_NUM 6

JNIEXPORT jstring
JNICALL Java_com_ys_usbreader_UsbReader_find( JNIEnv* env,
jclass cls)
{
int i;
char buf[64];
FILE *fp;

for (i=0;i<MAX_DIR_NUM;i++) {
sprintf(dev_path, DEV_PATH_DIR, i);
printf("dev_path=%s\n", dev_path);
fp = fopen(dev_path, "r");
if ( fp )   {
fgets(buf, sizeof(buf), fp);
fclose(fp);
printf("dev_name=%s\n", buf);
if ( strstr(buf, "Reader") || strstr(buf, "RFID")) {
sprintf(dev_path, "/dev/input/event%d", i);

return (*env)->NewStringUTF(env, dev_path);

}
}
}

return "";
}


JNIEXPORT jint
JNICALL Java_com_ys_usbreader_UsbReader_open( JNIEnv* env,
                                                  jclass cls)
{     
     int i;
     char buf[64];
     FILE *fp ;

     for (i=0;i<MAX_DIR_NUM;i++) {
        sprintf(dev_path,DEV_PATH_DIR,i);
        printf("dev_path=%s\n",dev_path);
        fp = fopen(dev_path,"r") ;
        if ( fp )   {
            fgets(buf,sizeof(buf),fp);
            fclose(fp);
            printf("dev_name=%s\n",buf);
            if  ( strstr(buf,"Reader") || strstr(buf,"RFID")) {
                  sprintf(dev_path,"/dev/input/event%d",i);
                  break;
            }
        }
     }


     printf("Reader at i=%d\n",i);

     if (i>=MAX_DIR_NUM){
         return -1 ;
     }
     printf("dev_path=%s\n",dev_path);

     printf("m_fd=%d\n",m_fd);
     if ( m_fd > 0 )  {  //alread opened
          return m_fd ;
     }
     m_fd = open(dev_path,O_RDONLY);
     if (m_fd < 0){
         printf("m_fd=%d\n",m_fd);
         return -1;
     }
     printf("%s open ok\n",dev_path);
     return m_fd;
}

JNIEXPORT void 
JNICALL Java_com_ys_usbreader_UsbReader_close( JNIEnv* env,
                                                  jclass cls)
{
     if ( m_fd > 0 ){
         close(m_fd);
         m_fd = -1 ; 
     }
     return ;
}

JNIEXPORT jstring
JNICALL Java_com_ys_usbreader_UsbReader_getCardNo( JNIEnv* env,
                                                  jclass cls)
{
        char buff[16];
        struct input_event key_event;  
        int count = 0 ;

        m_fd = open(dev_path,O_RDONLY);
     if (m_fd < 0){
return "";
}
        memset(buff,0x0,sizeof(buff));

        while(1)  {  

            if(read(m_fd, &key_event, sizeof(key_event)) == sizeof(key_event)) {  

                   if(key_event.type==EV_KEY &&  key_event.value==1)  {  
                        dbg_printf("key %d %s\n", key_event.code, (key_event.value) ? "Pressed" : "Released");  
                        switch(key_event.code) { 
                            case KEY_1:  
                            case KEY_2:  
                            case KEY_3:  
                            case KEY_4:  
                            case KEY_5:  
                            case KEY_6:  
                            case KEY_7:  
                            case KEY_8:  
                            case KEY_9:  
                                if (count < 16) { 
                                    buff[count++] = key_event.code -  KEY_1 +'1';
                                }
                                break;
                            case KEY_0:  
                                dbg_printf("count=%d\n",count);
                                if (count < 16) { 
                                    buff[count++] = '0';
                                }
                                break;
                            case KEY_ENTER:  
                                buff[count] = '\0';
                                dbg_printf("count=%d,key enter card_no=%s\n",count,buff);
                                return (*env)->NewStringUTF(env, buff);
                                break;
                            default:
                               break;
                        } //switch
                        if (count>=16) { 
                            break;
                        }
                   }  
            }  else {  //read error
                  break; 
            }
        }  //while

        return (*env)->NewStringUTF(env, buff);
}

